"""
A plugin arcitecture for Worde
"""
__revision__ = "$Id: plugins.py 47 2007-03-12 13:57:13Z jens.persson $"

import sys
import glob
import types


class Plugin(object):
    """
    Base class for all plugins in worde
    """
    pass


def prerender(text):
    """
    Hook called when the text in a post is updated.

    It should transform as much as possible of the text.
    """
    for plug in pluginhash["prerender"]:
        text = plug.prerender(text)
    return text

def prerender_comment(text):
    """
    Hook called when the text in a comment is changed

    It should transform as much as possible of the text.
    """
    for plug in pluginhash["prerender_comment"]:
        text = plug.prerender_comment(text)
    return text

def render(text, request):
    """
    Hook called when the text shall be displayed.

    It should only do the transforms that needs access to the
    request object.
    """
    for plug in pluginhash["render"]:
        text = plug.render(text, request)
    return text

def render_comment(text, request):
    """
    Hook called when a comment shall be displayed.

    It should only do the transforms that needs access to the
    request object.
    """
    for plug in pluginhash["render_comment"]:
        text = plug.render_comment(text, request)
    return text

def check_comment(comment, request):
    """
    Hook called when a comment is posted.

    The comment param is the comment,
    and request the request object creating the comment

    Thought for spam filtering, it could change the comment (or even
    remove it, returning None) before it is returnd
    """
    for plug in pluginhash["check_comment"]:
        if comment:
            comment = plug.check_comment(comment, request)

def sidebox(request):
    """
    Return a list of html sniplets that can be put in a sidebar
    """
    return [plug.sidebox(request) for plug in pluginhash["sidebox"]]

API = ["render", "prerender", "render_comment", "prerender_comment", "sidebox",
       "check_comment"]
pluginhash = {}

def find_plugins(directory):
    """
    Find all plugins in <directory>, lod them and store them
    """
    # Import needs to happen here to avoid circular dependensies
    from worde.model import PluginConfiguration
    sys.path = [directory] + sys.path
    modulenames = [fn[len(directory)+1:-3] for fn in glob.glob(directory+"/*.py")]
    plugs = []

    for modulename in modulenames:
        module = __import__(modulename)
        reload(module)
        for member in module.__dict__:
            if (type(module.__dict__[member]) == types.TypeType and
                    issubclass(module.__dict__[member], Plugin)):
                plugs.append(module.__dict__[member]())

    for hook in API:
        pluginhash[hook] = []

    for plugin in plugs:
        for hook in API:
            if hook in dir(plugin):
                conf = PluginConfiguration.get_singelton(plugin.__module__, plugin.__class__.__name__, hook)
                if conf.active:
                    pluginhash[hook].append((plugin, conf.ordering))

    for hook in API:
        pluginhash[hook].sort(lambda x,y: cmp(x[1],y[1]))
        pluginhash[hook] = [plug[0] for plug in pluginhash[hook]]

    PluginConfiguration.normalize_ordering()

    sys.path = sys.path[1:]